home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / dos6mm.zip / REMOVE.ASM < prev    next >
Assembly Source File  |  1993-03-31  |  18KB  |  368 lines

  1. ;****************************************************************************
  2. ; REMOVE removes a bookmark placed in memory by INSTALL. Its syntax is:
  3. ;
  4. ;       REMOVE [bookmark] [/L]
  5. ;
  6. ; where "bookmark" is the name of the bookmark to be removed from memory,
  7. ; and /L lists the bookmarks that are currently resident in memory. When
  8. ; a bookmark is removed, all the TSRs installed above it are removed also.
  9. ; Run with no command line parameters, REMOVE removes the highest bookmark
  10. ; in memory.
  11. ;****************************************************************************
  12.  
  13. nextblock       equ     0103h                   ;Offset of NEXTBLOCK field
  14. bm_addr         equ     0105h                   ;Offset of bookmark field
  15. vectors         equ     0133h                   ;Offset of vector field
  16.  
  17. code            segment
  18.                 assume  cs:code,ds:code
  19.                 org     100h
  20. begin:          jmp     main
  21.  
  22. helpmsg         db      "Removes a bookmark created with INSTALL."
  23.                 db      13,10,13,10
  24.                 db      "REMOVE [bookmark] [/L]",13,10,13,10
  25.                 db      "  bookmark  Name of the bookmark to remove.",13,10
  26.                 db      "  /L        List the bookmarks currently "
  27.                 db      "installed.",13,10,13,10
  28.                 db      "Run with no parameters, REMOVE removes the most "
  29.                 db      "recently installed bookmark.",13,10
  30.                 db      "When a bookmark is removed, all the TSRs installed "
  31.                 db      "after it are removed, too.",13,10,"$"
  32.  
  33. errmsg1         db      "Syntax: REMOVE [bookmark] [/L]",13,10,"$"
  34. errmsg2         db      "Requires DOS 3.0 or higher",13,10,"$"
  35. errmsg3         db      "There are no bookmarks installed",13,10,"$"
  36. errmsg4         db      "There is no bookmark by that name",13,10,"$"
  37. errmsg5         db      "Memory deallocation failed",13,10,"$"
  38.  
  39. msg1            db      "REMOVE 1.3 Copyright (c) 1993 Jeff Prosise",13,10
  40.                 db      "From: PC Magazine DOS 6 Memory Management "
  41.                 db      "with Utilities",13,10,13,10
  42.                 db      "Bookmark $"
  43. msg2            db      " removed"
  44. crlf            db      13,10,"$"
  45.  
  46. lastblock       dw      ?                       ;Segment of last block
  47. bookmark        db      33 dup (0Dh)            ;Bookmark name
  48. signature       db      0,1,2,"INSTALL",2,1,0   ;INSTALL signature
  49.  
  50. ;****************************************************************************
  51. ; Procedure MAIN
  52. ;****************************************************************************
  53.  
  54. main            proc    near
  55.                 cld                             ;Clear direction flag
  56.                 mov     si,81h                  ;Point SI to command line
  57.                 call    scanhelp                ;Scan for "/?" switch
  58.                 jnc     checkver                ;Branch if not found
  59.                 mov     ah,09h                  ;Display help text and exit
  60.                 mov     dx,offset helpmsg       ;with ERRORLEVEL=0
  61.                 int     21h
  62.                 mov     ax,4C00h
  63.                 int     21h
  64. ;
  65. ; Check the DOS version.
  66. ;
  67. checkver:       mov     dx,offset errmsg2       ;Exit if DOS version
  68.                 mov     ah,30h                  ;is less than 3.0
  69.                 int     21h
  70.                 cmp     al,3
  71.                 jae     checkins
  72.  
  73. error:          mov     ah,09h                  ;Display error message and
  74.                 int     21h                     ;exit with ERRORLEVEL=1
  75.                 mov     ax,4C01h
  76.                 int     21h
  77.  
  78. checkins:       call    check_install           ;See if INSTALL is installed
  79.                 mov     dx,offset errmsg3
  80.                 jnc     error                   ;Exit if it's not
  81. ;
  82. ; Parse the command line.
  83. ;
  84.                 mov     lastblock,cs            ;Initialize LASTBLOCK
  85.                 mov     si,81h                  ;Reset SI
  86.                 call    findchar                ;Find the first parameter
  87.                 jc      search1                 ;Branch if there are none
  88.                 cmp     byte ptr [si],"/"       ;Branch if the character
  89.                 jne     parse                   ;is not a "/"
  90. ;
  91. ; Process a /L switch.
  92. ;
  93. list:           inc     si                      ;Skip the "/" character
  94.                 lodsb                           ;Get the next character
  95.                 and     al,0DFh                 ;Capitalize it
  96.                 mov     dx,offset errmsg1       ;Initialize error pointer
  97.                 cmp     al,"L"                  ;Error if the character is
  98.                 jne     error                   ;not an "L"
  99.  
  100. nextname:       mov     di,bm_addr              ;Point DI to bookmark name
  101.                 call    dos_out                 ;Display bookmark name
  102.                 mov     ah,09h                  ;Move the cursor to the
  103.                 mov     dx,offset crlf          ;next line
  104.                 int     21h
  105.                 cmp     word ptr es:[nextblock],0FFFFh  ;Exit if this is the
  106.                 je      list_exit                       ;last block
  107.                 mov     es,es:[nextblock]       ;Get segment of next block
  108.                 jmp     nextname                ;Go back and output its name
  109.  
  110. list_exit:      mov     ax,4C00h                ;Exit with ERRORLEVEL=0
  111.                 int     21h
  112. ;
  113. ; Read the bookmark name from the command line.
  114. ;
  115. parse:          mov     di,offset bookmark      ;Point DI to buffer
  116.                 mov     cx,32                   ;Initialize counter
  117. parse1:         lodsb                           ;Get a character
  118.                 cmp     al,"a"                  ;Capitalize it if it's
  119.                 jb      parse2                  ;between "a" and "z"
  120.                 cmp     al,"z"
  121.                 ja      parse2
  122.                 and     al,0DFh
  123. parse2:         mov     [di],al                 ;Store it
  124.                 inc     di                      ;Increment DI
  125.                 cmp     al,0Dh                  ;Branch if it was a carriage
  126.                 je      search                  ;return
  127.                 loop    parse1                  ;Loop back for more
  128. ;
  129. ; Search out a bookmark.
  130. ;
  131. search:         mov     si,offset bookmark      ;Point SI to local name
  132.                 mov     di,bm_addr              ;Point DI to remote name
  133.                 call    compare_names           ;Compare the two
  134.                 je      endchain                ;Branch if they're equal
  135.                 mov     dx,offset errmsg4
  136.                 cmp     word ptr es:[nextblock],0FFFFh
  137.                 je      error                   ;Error if last block
  138.                 mov     lastblock,es            ;Save last block address
  139.                 mov     es,es:[nextblock]       ;Get address of next block
  140.                 jmp     search                  ;Return to search loop
  141.  
  142. search1:        cmp     word ptr es:[nextblock],0FFFFh
  143.                 je      endchain                ;Branch if last block
  144.                 mov     lastblock,es            ;Save last block address
  145.                 mov     es,es:[nextblock]       ;Get address of next block
  146.                 jmp     search1                 ;Continue the search
  147. ;
  148. ; Terminate the chain of INSTALLed blocks and restore interrupt vectors.
  149. ;
  150. endchain:       push    es                      ;Save ES
  151.                 mov     es,lastblock            ;Retrieve last block address
  152.                 mov     word ptr es:[nextblock],0FFFFh  ;Terminate the chain
  153.                 pop     es                      ;Restore ES
  154.                 mov     lastblock,es            ;Save ES in LASTBLOCK
  155.  
  156.                 push    ds                      ;Save DS and ES
  157.                 push    es
  158.                 mov     ax,es                   ;Point DS:SI to copy of
  159.                 mov     ds,ax                   ;interrupt vectors in
  160.                 assume  ds:nothing              ;INSTALLed block
  161.                 mov     si,vectors
  162.                 sub     di,di                   ;Point ES:DI to 0000:0000
  163.                 mov     es,di
  164.                 mov     cx,512                  ;Initialize counter
  165.                 cli                             ;Disable interrupts
  166.                 rep     movsw                   ;Restore interrupt vectors
  167.                 sti                             ;Enable interrupts
  168.                 pop     es                      ;Restore DS and ES
  169.                 pop     ds
  170.                 assume  ds:code
  171. ;
  172. ; Search out every PSP block above INSTALL and deallocate the memory that
  173. ; belongs to it.
  174. ;
  175.                 mov     bx,es                   ;Transfer ES to BX
  176.                 mov     ah,49h                  ;Deallocate the memory used
  177.                 int     21h                     ;by INSTALL
  178.                 mov     dx,offset errmsg5       ;Initialize error pointer
  179.                 jc      error1                  ;Error if call failed
  180.  
  181. remove:         dec     bx                      ;Point BX to MCB
  182.                 mov     es,bx                   ;Transfer BX to ES
  183.                 add     bx,es:[03h]             ;Compute next MCB address
  184.                 inc     bx
  185.                 mov     es,bx                   ;Transfer segment to ES
  186.                 inc     bx                      ;Point BX to segment beyond
  187.                 cmp     bx,es:[01h]             ;Does the segment own itself?
  188.                 jne     remove                  ;No, then continue searching
  189.                 mov     ax,cs                   ;Record current segment in AX
  190.                 cmp     bx,ax                   ;Have we reached our own PSP?
  191.                 je      done                    ;Yes, then we're done
  192.  
  193.                 push    bx                      ;Save PSP segment address
  194.                 call    freemem                 ;Free all memory it owns        
  195.                 pop     bx                      ;Retrieve the address
  196.                 mov     dx,offset errmsg5       ;Loop back if no error
  197.                 jnc     remove                  ;occurred
  198.  
  199. error1:         jmp     error                   ;Exit on error
  200. ;
  201. ; Announce that REMOVE succeeded and terminate.
  202. ;
  203. done:           mov     ah,09h                  ;Display message verifying
  204.                 mov     dx,offset msg1          ;that the book mark was
  205.                 int     21h                     ;removed
  206.                 mov     es,lastblock
  207.                 mov     di,bm_addr
  208.                 call    dos_out
  209.                 mov     ah,09h
  210.                 mov     dx,offset msg2
  211.                 int     21h
  212.  
  213.                 mov     ax,4C00h                ;Exit with ERRORLEVEL=0
  214.                 int     21h
  215. main            endp
  216.  
  217. ;****************************************************************************
  218. ; FINDCHAR advances SI to the next non-white-space character. On return,
  219. ; carry set indicates EOL was encountered.
  220. ;****************************************************************************
  221.  
  222. findchar        proc    near
  223.                 lodsb                           ;Get the next character
  224.                 cmp     al,09h                  ;Loop if tab
  225.                 je      findchar
  226.                 cmp     al,20h                  ;Loop if space
  227.                 je      findchar
  228.                 cmp     al,2Ch                  ;Loop if comma
  229.                 je      findchar
  230.                 dec     si                      ;Point SI to the character
  231.                 cmp     al,0Dh                  ;Exit with carry set if end
  232.                 je      eol                     ;of line is reached
  233.  
  234.                 clc                             ;Clear carry and exit
  235.                 ret
  236.  
  237. eol:            stc                             ;Set carry and exit
  238.                 ret
  239. findchar        endp
  240.  
  241. ;****************************************************************************
  242. ; SCANHELP scans the command line for a /? switch. If found, carry returns
  243. ; set and SI contains its offset. If not found, carry returns clear.
  244. ;****************************************************************************
  245.  
  246. scanhelp        proc    near
  247.                 push    si                      ;Save SI
  248. scanloop:       lodsb                           ;Get a character
  249.                 cmp     al,0Dh                  ;Exit if end of line
  250.                 je      scan_exit
  251.                 cmp     al,"?"                  ;Loop if not "?"
  252.                 jne     scanloop
  253.                 cmp     byte ptr [si-2],"/"     ;Loop if not "/"
  254.                 jne     scanloop
  255.  
  256.                 add     sp,2                    ;Clear the stack
  257.                 sub     si,2                    ;Adjust SI
  258.                 stc                             ;Set carry and exit
  259.                 ret
  260.  
  261. scan_exit:      pop     si                      ;Restore SI
  262.                 clc                             ;Clear carry and exit
  263.                 ret
  264. scanhelp        endp
  265.  
  266. ;****************************************************************************
  267. ; CHECK_INSTALL returns carry set if a copy of INSTALL is installed,
  268. ; carry clear if it's not. If carry returns set, AH holds INSTALL's
  269. ; multiplex ID number and ES holds its segment address.
  270. ;****************************************************************************
  271.  
  272. check_install   proc    near
  273.                 mov     ax,0C000h               ;Initialize AH and AL
  274.                 mov     cx,40h                  ;Initialize count
  275.  
  276. chinst1:        push    ax                      ;Save AX and CX
  277.                 push    cx
  278.                 sub     di,di                   ;Set ES and DI to 0
  279.                 mov     es,di
  280.                 int     2Fh                     ;Interrupt 2Fh
  281.                 cmp     al,0FFh                 ;Nothing here if AL isn't
  282.                 jne     chinst2                 ;equal to FFH
  283.  
  284.                 mov     si,offset signature     ;See if program signature
  285.                 mov     cx,13                   ;appears at the address
  286.                 repe    cmpsb                   ;returned in ES:DI
  287.                 jne     chinst2                 ;Branch if it does not
  288.  
  289.                 pop     cx                      ;Clear the stack and exit
  290.                 pop     ax                      ;with carry set
  291.                 stc
  292.                 ret
  293.  
  294. chinst2:        pop     cx                      ;Retrieve AX and CX
  295.                 pop     ax
  296.                 inc     ah                      ;Next multiplex ID
  297.                 loop    chinst1                 ;Loop until done
  298.  
  299.                 clc                             ;Exit with carry clear
  300.                 ret
  301. check_install   endp
  302.  
  303. ;****************************************************************************
  304. ; FREEMEM frees all the memory blocks owned by the process whose PSP
  305. ; address is passed in BX. Carry is set on return if a call to release
  306. ; a block of memory failed.
  307. ;****************************************************************************
  308.  
  309. freemem         proc    near
  310.                 push    bx                      ;Save BX
  311.                 mov     ah,52h                  ;Get address of the first
  312.                 int     21h                     ;MCB with DOS function 52H
  313.                 mov     dx,es:[bx-2]            ;Copy the address to DX
  314.                 mov     es,dx                   ;Also copy it to ES
  315.                 pop     bx                      ;Restore BX
  316.  
  317. free1:          cmp     bx,es:[01h]             ;Branch if the ownership
  318.                 jne     free2                   ;word does not match
  319.  
  320.                 inc     dx                      ;Increment DX
  321.                 mov     es,dx                   ;Point ES to segment
  322.                 mov     ah,49h                  ;Deallocate the segment
  323.                 int     21h
  324.                 jc      free_exit               ;Exit if called failed
  325.                 dec     dx                      ;Decrement DX
  326.                 mov     es,dx                   ;Point ES back to the MCB
  327.  
  328. free2:          add     dx,es:[03h]             ;Compute the address of the
  329.                 inc     dx                      ;next MCB
  330.                 mov     es,dx                   ;Transfer address to ES
  331.                 cmp     byte ptr es:[00h],"Z"   ;End of the MCB chain?
  332.                 jne     free1                   ;No, then continue the search
  333.                 clc                             ;Clear carry and exit
  334. free_exit:      ret
  335. freemem         endp
  336.  
  337. ;****************************************************************************
  338. ; COMPARE_NAMES compares the two ASCII strings addressed by DS:SI and ES:DI.
  339. ; On return, the Z flag indicates whether or not the two are equal.
  340. ;****************************************************************************
  341.  
  342. compare_names   proc    near
  343.                 lodsb                           ;Get a character
  344.                 cmp     al,0Dh                  ;Exit if it's a carriage
  345.                 je      compare_exit            ;return
  346.                 scasb                           ;Compare it ES:[DI]
  347.                 je      compare_names           ;Loop back if they're euqal
  348. compare_exit:   ret                             ;Return to caller
  349. compare_names   endp
  350.  
  351. ;****************************************************************************
  352. ; DOS_OUT displays the ASCII string pointed to by ES:DI.
  353. ;****************************************************************************
  354.  
  355. dos_out         proc    near
  356.                 mov     dl,es:[di]              ;Get a character
  357.                 cmp     dl,0Dh                  ;Exit if it's a carriage
  358.                 je      dos_exit                ;return
  359.                 mov     ah,02h                  ;Output it using DOS
  360.                 int     21h                     ;function 02H
  361.                 inc     di                      ;Advance DI to next one
  362.                 jmp     dos_out                 ;Loop until done
  363. dos_exit:       ret
  364. dos_out         endp
  365.  
  366. code            ends
  367.                 end     begin
  368.